'use strict';
/* 加载插件 */
const gulp = require('gulp');
/* gulp-load-plugins只能加载gulp开头的插件，并遵循驼峰式写法 */
const $ = require('gulp-load-plugins')();
/* 加载px转rem插件 */
const rem = require('postcss-px2rem');
/* 加载热加载服务插件 */
$.browserSync = require('browser-sync').create();

/* 资源出入口 */
const output = __dirname + '/dist'; // 资源出口
const input = __dirname + '/src'; // 资源入口

/* opt: 资源地址 */
const opt = {
  html: '/page', // html文件位置
  preStyle: '/scss', // scss文件位置
  style: '/css', // css文件位置
  script: '/js', // js文件位置
  image: '/image', // 图片文件位置
  icon: '/image/icon', // icon图标文件位置
  sprite: '/image/sprite' // 雪碧图文件位置
};

/* DEV:执行环境 */
let DEV = false; // false:开发环境, true:生产环境

/* 热加载服务 */
gulp.task('server', () => {
  // 初始化服务器
  $.browserSync.init({
    // 服务器配置
    server: {
      // 可访问文件夹
      baseDir: output,
      // 指定服务器打开页面文件
      index: 'index.html'
    }
  });
  // 监听目录下所有文件，一旦发生改变重启服务器
  gulp.watch(output + '/**/*.*').on('change', $.browserSync.reload);
});

/* 重启服务器 */
gulp.task('reload', () => {
  //重启服务器
  $.browserSync.reload();
});


/* 定义自动化操作之前清空目的文件夹 */
gulp.task('clean', () => {
  // 指定清除文件目录，read:false(直接删除)
  gulp.src([output + '/*'], {
      read: false
    })
    // 执行清除方法
    .pipe($.clean());
});


/* html压缩 */
gulp.task('minifyHtml', () => {
  // 指定html文件位置
  return gulp.src(input + '/**/*.html')
    // 生产环境，替换文件名
    .pipe($.if(DEV, $.rename({
      suffix: '.min'
    })))
    // 生产环境，执行压缩
    .pipe($.if(DEV, $.minifyHtml()))
    // 生产环境 set hash key
    .pipe($.if(DEV, $.rev()))
    // 导出html文件
    .pipe(gulp.dest(output))
    // 生产环境 set hash key json
    .pipe($.if(DEV, $.rev.manifest()))
    // 生产环境 dest hash key json
    .pipe($.if(DEV, gulp.dest(__dirname + '/rev/html')));
});


/* css压缩 */
gulp.task('minifyCss', () => {
  // 指定css文件位置
  return gulp.src(input + opt.style + '/**/*.css')
    // 生产环境，替换文件名
    .pipe($.if(DEV, $.rename({
      suffix: '.min'
    })))
    // 自动补全浏览器样式兼容
    .pipe($.autoprefixer())
    // 生产环境，压缩css文件
    .pipe($.if(DEV, $.minifyCss()))
    // 生产环境 set hash key
    .pipe($.if(DEV, $.rev()))
    // 导出css文件
    .pipe(gulp.dest(output + opt.style))
    // 生产环境 set hash key json
    .pipe($.if(DEV, $.rev.manifest()))
    // 生产环境 dest hash key json
    .pipe($.if(DEV, gulp.dest(__dirname + '/rev/style')));
});


/* js压缩 */
gulp.task('uglify', () => {
  // 指定js文件位置
  return gulp.src(input + opt.script + '/**/*.js')
    // 生产环境，替换文件名
    .pipe($.if(DEV, $.rename({
      suffix: '.min'
    })))
    // 生产环境，压缩js文件
    .pipe($.if(DEV, $.uglify()))
    // 生产环境 set hash key
    .pipe($.if(DEV, $.rev()))
    // 导出js文件
    .pipe(gulp.dest(output + opt.script))
    // 生产环境 set hash key json
    .pipe($.if(DEV, $.rev.manifest()))
    // 生产环境 dest hash key json
    .pipe($.if(DEV, gulp.dest(__dirname + "/rev/script")));
});


/* 编译sass */
gulp.task('sass', () => {
  // 指定文件位置
  return gulp.src(input + opt.preStyle + '/**/*.scss')
    // 编译sass
    .pipe($.sass())
    // 异常捕获
    .pipe($.plumber())
    // 编译完成，导出css文件
    .pipe(gulp.dest(input + opt.style));
});


/* 压缩图片 */
gulp.task('imagemin', () => {
  // 指定图片文件路径及文件类型
  return gulp.src(input + opt.image + '/**/*.{jpg,jpeg,gif,webp,apng,png}')
    .pipe($.if(DEV, $.imagemin({
      // 类型：Number  默认：3  取值范围：0-7（优化等级）
      optimizationLevel: 0,
      // 类型：Boolean 默认：false 无损压缩jpg图片
      progressive: true,
      // 类型：Boolean 默认：false 隔行扫描gif进行渲染
      interlaced: true
    })))
    // 导出图片文件
    .pipe(gulp.dest(output + opt.image))
});

/* 转换webp */
gulp.task('webp', () => {
  // 指定图片文件路径及文件类型
  return gulp.src(output + opt.image + '/**/*.{jpg,jpeg,gif,webp,apng,png}')
    // 转换为webp
    .pipe($.webp())
    // 导出图片文件
    .pipe(gulp.dest(output + opt.image));
});


/* 合成雪碧图 */
gulp.task('spritesmith', () => {
  // 指定文件入口
  return gulp.src(input + opt.icon + '/**/*.png')
    .pipe($.spritesmith({
      // 指定二倍图
      retinaSrcFilter: ['./image/*@2x.png'],
      // 指定生产的二倍图文件名
      retinaImgName: 'sprite@2x.png',
      // 生产css文件名
      cssName: 'sprite.css',
      // 生产的png文件名
      imgName: 'sprite.png',
      // 图标排列方式
      algorithm: 'top-down',
      // 图标间隙
      padding: 0
    }))
    // 文件出口
    .pipe(gulp.dest(output + opt.sprite));
});


/* rem转换 */
gulp.task('rem', () => {
  // 指定设计图大小，单位px
  var px2rem = [rem({
    //指定设计图尺寸
    remUnit: 75
  })];
  // 指定文件入口
  return gulp.src(output + opt.style + '/**/*.css')
    // 将px转换为rem
    .pipe($.postcss(px2rem))
    // 导出css文件
    .pipe(gulp.dest(output + opt.style));
});


/* 静态资源路径替换 */
gulp.task('rev', () => {
  // 指定清单文件路径
  return gulp.src([__dirname + '/rev/**/*.json', input + '/**/*.{html,css}'])
    .pipe($.revCollector({
      // 已经被替换的文件是否还能再被替换,默认是false
      replaceReved: true,
      // 文件目录信息
      dirReplacements: {}
    }))
    .pipe(gulp.dest(output))
});

/* 帮助 */
gulp.task('help', () => {
  console.log('gulp minifyHtml : 压缩html文件');
  console.log('gulp minifyCss : 压缩css文件');
  console.log('gulp uglify : 压缩js文件');
  console.log('gulp imagemin : 压缩图片文件');
  console.log('gulp webp : 图片转webp')
  console.log('gulp sass : 编译sass');
  console.log('gulp rem : px转换rem');
  console.log('gulp clean : 清空dist目录');
  console.log('gulp server : 启动服务器');
  console.log('gulp reload : 重启服务器');
})

/* 监听文件变更 */
gulp.task('watch', () => {
  gulp.watch(input + '/**/*.html', ['minifyHtml']);
  gulp.watch(input + opt.style + '/**/*.css', ['minifyCss']);
  gulp.watch(input + opt.script + '/**/*.js', ['uglify']);
  gulp.watch(input + opt.preStyle + '/**/*.scss', ['sass']);
  gulp.watch(output + opt.style + '/**/*.css', ['rem']);
});

/** 
 * 开发环境
 * 依次执行任务,命令: gulp 
 */
gulp.task("default", $.sequence("clean", "sass", "minifyHtml", "minifyCss", "uglify", "rem", "imagemin", "watch", "server"));


/** 
 * 生产环境
 * 依次执行任务,命令L: gulp prod 
 */
gulp.task("prod", () => {
  DEV = true;
  $.sequence("clean", "sass", "minifyHtml", "minifyCss", "uglify", "imagemin", "rev");
});